package com.maxd.controller.cash;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.maxd.adapter.IgnoreSecurity;
import com.maxd.constants.AliPayConstants;
import com.maxd.error.ExceptionEnum;
import com.maxd.error.Result;
import com.maxd.error.ResultUtil;
import com.maxd.model.*;
import com.maxd.modules.selfshop.merchants.entity.SelfMerchantApply;
import com.maxd.modules.selfshop.merchants.entity.SelfStore;
import com.maxd.modules.selfshop.merchants.respository.SelfMerchantApplyJpaRepository;
import com.maxd.modules.selfshop.merchants.respository.SelfStoreJpaRepository;
import com.maxd.respository.cash.CashJpaRepository;
import com.maxd.respository.cash.CashRepository;
import com.maxd.respository.common.CommonRepository;
import com.maxd.respository.selfActivity.SelfActivityJpaRepository;
import com.maxd.respository.selfActivity.SelfActivityRepository;
import com.maxd.respository.userinfo.UserJpaRepository;
import com.maxd.respository.userinfo.UserRepository;
import com.maxd.service.cash.ICashService;
import com.maxd.service.message.IMessageService;
import com.maxd.service.money.IMoneyDetailsService;
import com.maxd.service.pay.PayDetailsService;
import com.maxd.service.userinfo.UserServiceImpl;
import com.maxd.service.wx.AccountService;
import com.maxd.service.wx.AccountTokenServiceImpl;
import com.maxd.utils.*;
import com.maxd.utils.wx.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*;
import weixin.popular.bean.message.templatemessage.TemplateMessageItem;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.io.StringReader;
import java.math.BigDecimal;
import java.security.PublicKey;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;

@Slf4j
@RestController
@Api(value = "用户结算管理", tags = {"用户结算管理"})
@RequestMapping(value = "/cash")
public class CashController {
    private Logger logger = LoggerFactory.getLogger(CashController.class);
    @Autowired
    private ICashService iCashService;
    @Autowired
    private UserJpaRepository userJpaRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private CashJpaRepository cashJpaRepository;
    @Autowired
    private CashRepository cashRepository;
    @Autowired
    private CommonRepository commonRepository;
    @Autowired
    private AccountService accountService;
    @Autowired
    private UserServiceImpl userService;
    @Autowired
    private IMessageService iMessageService;
    @Autowired
    private IMoneyDetailsService iMoneyDetailsService;
    @Autowired
    private PayDetailsService payDetailsService;
    @Autowired
    private SelfMerchantApplyJpaRepository selfMerchantApplyJpaRepository;
    @Autowired
    private SelfStoreJpaRepository selfStoreJpaRepository;
    @Autowired
    private SelfActivityRepository selfActivityRepository;
    private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(true);

    private ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().build();
    private ExecutorService singleThreadPool = new ThreadPoolExecutor(30, 100,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(1024), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());



    @RequestMapping(value = "/sendMsg", method = RequestMethod.GET)
    @ApiOperation("管理平台主动推送消息")
    @ResponseBody
    public Result sendMsg(String title, String content, String phone, Integer flag,Integer state) {
        if (flag == 1) {
            //根据手机号推送
            UserInfo userByPhone = userRepository.getUserByPhone(phone);
            if (null == userByPhone) {
                return ResultUtil.error(-100, "手机号不存在！");
            }
            send(userByPhone, title, content,state);
        } else {
            //所有人推送
            List<UserInfo> userInfos = userRepository.selectUserList();
            //用户数量较大  使用多线程推送  根据用户数量进行拆分  同时按照3个线程进行推送
            int count = userInfos.size() / 3;
            singleThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < count; i++) {
                        send(userInfos.get(i), title, content,state);
                    }
                }
            });
            singleThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = count; i < count * 2; i++) {
                        send(userInfos.get(i), title, content,state);
                    }
                }
            });
            singleThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int i = count * 2; i < userInfos.size(); i++) {
                        send(userInfos.get(i), title, content,state);
                    }
                }
            });
        }
        return ResultUtil.success();
    }


    private void send(UserInfo userByPhone, String title, String content,Integer state) {
        if (userByPhone.getClientid() != null) {
            userService.pushToSingle(title, content, userByPhone.getClientid());
        }
        MessageInfo messageInfo = new MessageInfo();
        messageInfo.setContent(content);
        messageInfo.setTitle(title);
        messageInfo.setState(String.valueOf(state));
        messageInfo.setUserName(userByPhone.getNickName());
        messageInfo.setUserId(String.valueOf(userByPhone.getId()));
        iMessageService.saveBody(messageInfo);
    }

    /**
     * 查询充值记录
     *
     * @return
     */
    @RequestMapping(value = "/selectPayDetails", method = RequestMethod.POST)
    @ApiOperation("查询充值记录")
    @ResponseBody
    public Result selectPayDetails(int page, int size, String phone, String startTime, String endTime) {
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(page, size, Sort.by(order));
        return ResultUtil.success(payDetailsService.selectPayDetails(pageable, phone, startTime, endTime));
    }

    /*@RequestMapping(value = "/selectCashList", method = RequestMethod.GET)
    @ApiOperation("管理平台查询用户提现列表")
    @ResponseBody
    public Result getList(Integer page,Integer size,String zhifubao,String relationId,Integer state) {
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(page, size, Sort.by(order));
        //构造自定义查询条件
        Specification<CashOut> queryCondition = new Specification<CashOut>() {
            @Override
            public Predicate toPredicate(Root<CashOut> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();
                if (StringUtils.isNotEmpty(zhifubao)) {
                    predicateList.add(criteriaBuilder.like(root.get("zhifubao"), zhifubao));
                }
                if (StringUtils.isNotEmpty(relationId)) {
                    predicateList.add(criteriaBuilder.equal(root.get("relationId"), relationId));
                }
                if (state != 2) {
                    predicateList.add(criteriaBuilder.equal(root.get("state"), state));
                }
                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
        return ResultUtil.success(cashJpaRepository.findAll(queryCondition, pageable));
    }*/

    /**
     * 管理平台查询某个用户的提现记录
     *
     * @return
     */
    @RequestMapping(value = "/phone/{phone}", method = RequestMethod.GET)
    @ApiOperation("管理平台查询某个用户的提现记录")
    @ResponseBody
    public Result findByPhone(@PathVariable String phone) {
        return iCashService.findByPhone(phone);
    }

    /**
     * 管理平台查询用户提现列表
     *
     * @param page
     * @param size
     * @return
     */
    @RequestMapping(value = "/page/{page}/{size}", method = RequestMethod.GET)
    @ApiOperation("管理平台查询用户提现列表")
    @ResponseBody
    public Result getLists(@PathVariable int page, @PathVariable int size) {
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(page, size, Sort.by(order));
        return ResultUtil.success(cashJpaRepository.findAll(pageable));
    }

    @RequestMapping(value = "/selectCashList", method = RequestMethod.GET)
    @ApiOperation("管理平台查询用户提现列表")
    @ResponseBody
    public Result selectCashList(Integer page, Integer size, String zhifubaoName, String relationId, Integer state, Integer type) {
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(page, size, Sort.by(order));
        return ResultUtil.success(cashRepository.selectCashList(pageable, zhifubaoName, relationId, state, type));
    }

    @ApiOperation("财务提现统计")
    @GetMapping("/statisticsCashMoney")
    public Result statisticsMoney(String time) {
        BigDecimal sumMoney = cashRepository.selectSumCashOutByState(time, 1);
        BigDecimal stayMoney = cashRepository.selectSumCashOutByState(time, 0);
        Map<String, Object> map = new HashMap<>();
        map.put("sumMoney", sumMoney == null ? 0.00 : sumMoney);
        map.put("stayMoney", stayMoney == null ? 0 : stayMoney);
        return ResultUtil.success(map);
    }


    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ApiOperation("管理平台修改用户提现状态")
    @ResponseBody
    public Result updateIsOut(@RequestParam Boolean isOut, @RequestParam Long id) {
        return iCashService.updateIsOut(isOut, id);
    }


    /**
     * 管理平台确认提现
     *
     * @param cashId
     * @return
     */
    @RequestMapping(value = "/update/{cashId}", method = RequestMethod.POST)
    @ApiOperation("管理平台确认提现")
    @ResponseBody
    public Result update(@PathVariable Long cashId) {
        CashOut one1 = cashJpaRepository.findById(cashId).orElse(null);
        CommonInfo url = commonRepository.findOne(19);
        CashOut one = cashJpaRepository.findById(cashId).orElse(null);
        if (one == null) {
            return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
        }
        assert one1 != null;
        if (one1.getOut()) {
            return ResultUtil.error(9999, one1.getZhifubaoName() + "转账失败！原因是用户已转账");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date now = new Date();
        one.setOut(true);
        one.setOutAt(sdf.format(now));
        CashOut save = cashJpaRepository.save(one);
        String userId = save.getUserId();
        UserInfo userInfo = userJpaRepository.getOne(Long.valueOf(userId));
        if (userInfo != null && userInfo.getOpenId() != null) {
            //推送提现通知消息
            cashOutSuccess(userInfo.getOpenId(), save.getOutAt(), save.getMoney(), save.getZhifubao(), url.getValue());
        }
        return ResultUtil.success(one1.getZhifubaoName() + "转账成功");
    }


    @RequestMapping(value = "/alipay/{cashId}", method = RequestMethod.POST)
    @ApiOperation("管理平台确认提现")
    @ResponseBody
    public Result alipayPay(@PathVariable Long cashId) {
        reentrantReadWriteLock.writeLock().lock();
        try {
/**
 * 初始化客户端
 */
            AlipayClient alipayClient = new DefaultAlipayClient(AliPayConstants.REQUEST_URL,
                    commonRepository.findOne(63).getValue(), commonRepository.findOne(65).getValue(), AliPayConstants.FORMAT,
                    AliPayConstants.CHARSET, commonRepository.findOne(64).getValue(), AliPayConstants.SIGNTYPE);
            CashOut one1 = cashJpaRepository.findById(cashId).orElse(null);
            //获取全局名称
            //是否开启企业支付
            CommonInfo commonInfo = commonRepository.findOne(51);
            CashOut one = cashJpaRepository.findById(cashId).orElse(null);
            if (one == null) {
                return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
            }
            if (StringUtils.isEmpty(one.getOrderNumber())) {
                String date = String.valueOf(System.currentTimeMillis());
                one.setOrderNumber(date);
            }
            assert one1 != null;
            if (one1.getOut()) {
                return ResultUtil.error(9999, one1.getZhifubaoName() + "转账失败！原因是用户已转账");
            }
            if (commonInfo.getValue() != null && commonInfo.getValue().equals("是")) {
                val aliPayWithdrawModel = AliPayWithdrawModel.builder()
                        .out_biz_no(one.getOrderNumber())
                        .amount(new BigDecimal(one.getMoney()))
                        .payee_account(one.getZhifubao())
                        .payee_real_name(one.getZhifubaoName())
                        .payee_type(AliPayConstants.PAY_TYPE)
                        .remark(commonRepository.findOne(12).getValue() + "佣金结算")
                        .build();
                String json = JSON.toJSONString(aliPayWithdrawModel);
                //实例化连接对象
                AlipayFundTransToaccountTransferRequest withdrawRequest = new AlipayFundTransToaccountTransferRequest();
                withdrawRequest.setBizContent(json);
                try {
                    AlipayFundTransToaccountTransferResponse response = alipayClient.execute(withdrawRequest);
                    if (AliPayConstants.SUCCESS_CODE.equalsIgnoreCase(response.getCode())) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        one.setOut(true);
                        one.setOutAt(sdf.format(new Date()));
                        CashOut save = cashJpaRepository.save(one);
                        UserInfo userInfo = userJpaRepository.getOne(Long.valueOf(save.getUserId()));
                        if (userInfo != null && userInfo.getOpenId() != null) {
                            //提现通知消息
                            cashOutSuccess(userInfo.getOpenId(), save.getOutAt(), save.getMoney(), save.getZhifubao(), commonRepository.findOne(19).getValue());
                        }
                        if (StringUtils.isNotEmpty(userInfo.getMpId())) {
                            CommonInfo msgs2 = commonRepository.findOne(295);
                            List<String> msgLists2 = new ArrayList<>();
                            msgLists2.add(save.getMoney());
                            msgLists2.add(save.getOutAt());
                            msgLists2.add("具体到账时间请已支付宝为主，注意查收");
                            AccountTokenServiceImpl.sendMsg(userInfo.getMpId(), msgs2.getValue(), msgLists2, 3);
                        }
                        return ResultUtil.success(one1.getZhifubaoName() + "转账成功");
                    } else {
                        return ResultUtil.error(9999, one1.getZhifubaoName() + "转账失败！" + response.getSubMsg());
                    }
                } catch (AlipayApiException e) {
                    logger.error("零钱提现异常原因:" + e.getMessage());
                    e.printStackTrace();
                    return ResultUtil.error(9999, one1.getZhifubaoName() + "转账失败！" + e.getMessage());

                }
            } else {
                //人工转账后改变状态的
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date now = new Date();
                one.setOut(true);
                one.setOutAt(sdf.format(now));
                CashOut save = cashJpaRepository.save(one);
                String userId = save.getUserId();
                UserInfo userInfo = userJpaRepository.getOne(Long.valueOf(userId));
                if (userInfo != null && userInfo.getOpenId() != null) {
                    //推送提现通知消息
                    cashOutSuccess(userInfo.getOpenId(), save.getOutAt(), save.getMoney(), save.getZhifubao(), commonRepository.findOne(19).getValue());
                }
                if (StringUtils.isNotEmpty(userInfo.getMpId())) {
                    CommonInfo msgs2 = commonRepository.findOne(295);
                    List<String> msgLists2 = new ArrayList<>();
                    msgLists2.add(save.getMoney());
                    msgLists2.add(save.getOutAt());
                    msgLists2.add("具体到账时间请已支付宝为主，注意查收");
                    AccountTokenServiceImpl.sendMsg(userInfo.getMpId(), msgs2.getValue(), msgLists2, 3);
                }
                return ResultUtil.success(one1.getZhifubaoName() + "转账成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("转账出错了:" + e.getMessage());
        } finally {
            reentrantReadWriteLock.writeLock().unlock();
        }
        return ResultUtil.error(-200, "系统繁忙，请稍后再试！");
    }

    @RequestMapping(value = "/v1/alipay/{cashId}", method = RequestMethod.POST)
    @ApiOperation("管理平台确认提现")
    @ResponseBody
    public Result v1alipayPay(@PathVariable Long cashId) {
        reentrantReadWriteLock.writeLock().lock();
        try {
            /**
             * 初始化客户端
             */
            AlipayClient alipayClient = new DefaultAlipayClient(AliPayConstants.REQUEST_URL,
                    commonRepository.findOne(63).getValue(), commonRepository.findOne(65).getValue(), AliPayConstants.FORMAT,
                    AliPayConstants.CHARSET, commonRepository.findOne(64).getValue(), AliPayConstants.SIGNTYPE);
            CashOut one1 = cashJpaRepository.findById(cashId).orElse(null);
            //获取全局名称
            //是否开启企业支付
            CommonInfo commonInfo = commonRepository.findOne(51);
            CashOut one = cashJpaRepository.findById(cashId).orElse(null);
            if (one == null) {
                return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
            }
            if (StringUtils.isEmpty(one.getOrderNumber())) {
                String date = String.valueOf(System.currentTimeMillis());
                one.setOrderNumber(date);
            }
            assert one1 != null;
            if (one1.getState() != 0) {
                return ResultUtil.error(9999, one1.getZhifubaoName() + "转账失败！原因是用户已转账");
            }

            if (commonInfo.getValue() != null && commonInfo.getValue().equals("是") && (one.getType() == null || one.getType() == 1)) {
                val aliPayWithdrawModel = AliPayWithdrawModel.builder()
                        .out_biz_no(one.getOrderNumber())
                        .amount(new BigDecimal(one.getMoney()))
                        .payee_account(one.getZhifubao())
                        .payee_real_name(one.getZhifubaoName())
                        .payee_type(AliPayConstants.PAY_TYPE)
                        .remark(commonRepository.findOne(12).getValue() + "佣金结算")
                        .build();
                String json = JSON.toJSONString(aliPayWithdrawModel);
                //实例化连接对象
                AlipayFundTransToaccountTransferRequest withdrawRequest = new AlipayFundTransToaccountTransferRequest();
                withdrawRequest.setBizContent(json);
                try {
                    AlipayFundTransToaccountTransferResponse response = alipayClient.execute(withdrawRequest);

                    if (AliPayConstants.SUCCESS_CODE.equalsIgnoreCase(response.getCode())) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        one.setState(1);
                        one.setOutAt(sdf.format(new Date()));
                        CashOut save = cashJpaRepository.save(one);
                        if (StringUtils.isNotEmpty(save.getUserId()) && save.getMerchantId() == null) {
                            UserInfo userInfo = userJpaRepository.getOne(Long.valueOf(save.getUserId()));
                            if (userInfo.getOpenId() != null) {
                                //提现通知消息
                                cashOutSuccess(userInfo.getOpenId(), save.getOutAt(), save.getMoney(), save.getZhifubao(), commonRepository.findOne(19).getValue());
                            }
                            if (StringUtils.isNotEmpty(userInfo.getMpId())) {
                                CommonInfo msgs2 = commonRepository.findOne(295);
                                List<String> msgLists2 = new ArrayList<>();
                                msgLists2.add(save.getMoney());
                                msgLists2.add(save.getOutAt());
                                msgLists2.add("具体到账时间请已支付宝为主，注意查收");
                                AccountTokenServiceImpl.sendMsg(userInfo.getMpId(), msgs2.getValue(), msgLists2, 3);
                            }
                        }
                        return ResultUtil.success(one1.getZhifubaoName() + "转账成功");
                    } else {
                        return ResultUtil.error(9999, one1.getZhifubaoName() + "转账失败！" + response.getSubMsg());
                    }
                } catch (AlipayApiException e) {
                    logger.error("零钱提现异常原因:" + e.getMessage());
                    e.printStackTrace();
                    return ResultUtil.error(9999, one1.getZhifubaoName() + "转账失败！" + e.getMessage());

                }
            } else if (one.getType() == 3) {
                //String value = commonRepository.findOne(304).getValue();
                /*if("1".equals(value)){
                    String nonceStr = WXPayUtil.generateNonceStr();

                    String rsa = "RSA/ECB/OAEPWITHSHA-1ANDMGF1PADDING";
                *//*StringBuffer pkcs1Path = new StringBuffer();
                pkcs1Path.append("classpath:").append("weixin/publicKey.pem");*//*
                *//*StringBuffer pkcs1Path = new StringBuffer();
                pkcs1Path.append("classpath:").append(keyfile);*//*
                    PublicKey pub = RSAUtils.getPubKey();
                    //PublicKey pub=RSAUtils.getPubKey();
                    byte[] estr = RSAUtils.encrypt(one.getBankCard().getBytes(), pub, 2048, 11, rsa);   //对银行账号进行加密
                    String encBankNo = WxBase64.encode(estr);//并转为base64格式
                    byte[] estr2 = RSAUtils.encrypt(one.getBankCarUserName().getBytes(), pub, 2048, 11, rsa);   //对银行账号进行加密
                    String encTrueName = WxBase64.encode(estr2);//并转为base64格式
                    String mchId = commonRepository.findOne(76).getValue();
                    SortedMap<String, String> parameters = new TreeMap<String, String>();
                    parameters.put("amount", new BigDecimal(one.getMoney()).multiply(new BigDecimal("100")).intValue() + "");
                    parameters.put("desc", commonRepository.findOne(12).getValue() + "佣金结算");
                    parameters.put("mch_id", mchId);
                    parameters.put("nonce_str", nonceStr);
                    parameters.put("enc_bank_no", encBankNo);
                    parameters.put("enc_true_name", encTrueName);
                    SelfActivity byTitle = selfActivityRepository.findByTitle(one.getBankCardName());
                    parameters.put("bank_code", byTitle.getContent());
                    parameters.put("partner_trade_no", one.getOrderNumber());
                    String key = commonRepository.findOne(75).getValue();

                    parameters.put("sign", WXPayUtil.generateSignature(parameters, key,
                            WXPayConstants.SignType.MD5));
                    String data = RSAUtils.SortedMaptoXml(parameters);
                    // 3.加载证书请求接口
                    System.out.println(data);
                    String result = RSAUtils.weChatWithdrawal(data);
                    log.error("------aaaaa------" + result);
                    boolean contains = result.contains("CDATA[FAIL]");
                    if (!contains) {
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        one.setState(1);
                        one.setOutAt(sdf.format(new Date()));
                        CashOut save = cashJpaRepository.save(one);
                        if (StringUtils.isNotEmpty(save.getUserId()) && save.getMerchantId() == null) {
                            UserInfo userInfo = userJpaRepository.getOne(Long.valueOf(save.getUserId()));
                            if (userInfo.getOpenId() != null) {
                                //提现通知消息
                                cashOutSuccess(userInfo.getOpenId(), save.getOutAt(), save.getMoney(), save.getBankCard(), commonRepository.findOne(19).getValue());
                            }
                            if (StringUtils.isNotEmpty(userInfo.getMpId())) {
                                CommonInfo msgs2 = commonRepository.findOne(295);
                                List<String> msgLists2 = new ArrayList<>();
                                msgLists2.add(save.getMoney());
                                msgLists2.add(save.getOutAt());
                                msgLists2.add("具体到账时间已银行为准，注意查收！");
                                AccountTokenServiceImpl.sendMsg(userInfo.getMpId(), msgs2.getValue(), msgLists2, 3);
                            }
                        }
                        return ResultUtil.success(one1.getZhifubaoName() + "转账成功");
                    } else {
                        SAXBuilder saxBuilder = new SAXBuilder();
                        Document doc = saxBuilder.build(new StringReader(result));
                        //成功 获取交易单号：return doc.getRootElement().getChild("payment_no").getValue();
                        String msg = doc.getRootElement().getChild("err_code_des").getValue();
                        return ResultUtil.error(-200, "转账失败，原因：" + msg);
                    }
                }else{*/
                    //人工转账后改变状态的
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Date now = new Date();
                    one.setState(1);
                    one.setOutAt(sdf.format(now));
                    CashOut save = cashJpaRepository.save(one);
                    if (save.getMerchantId() != null) {
                        return ResultUtil.success(one1.getZhifubaoName() + "转账成功");
                    }
                    String userId = save.getUserId();
                    UserInfo userInfo = userJpaRepository.getOne(Long.valueOf(userId));
                    if (userInfo.getOpenId() != null) {
                        //推送提现通知消息
                        cashOutSuccess(userInfo.getOpenId(), save.getOutAt(), save.getMoney(), save.getBankCard(), commonRepository.findOne(19).getValue());
                    }
                    if (StringUtils.isNotEmpty(userInfo.getMpId())) {
                        CommonInfo msgs2 = commonRepository.findOne(295);
                        List<String> msgLists2 = new ArrayList<>();
                        msgLists2.add(save.getMoney());
                        msgLists2.add(save.getOutAt());
                        msgLists2.add("具体到账时间请已银行为主，注意查收");
                        AccountTokenServiceImpl.sendMsg(userInfo.getMpId(), msgs2.getValue(), msgLists2, 3);
                    }
                    return ResultUtil.success(one1.getZhifubaoName() + "转账成功");
//                }

            } else if (one.getType() == 2) {
                WxPay wxPay = new WxPay();
                CommonInfo mchId = commonRepository.findOne(76);
                CommonInfo key = commonRepository.findOne(75);
                //小程序或公众号appid
                UserInfo userById = userRepository.getUserById(Long.parseLong(one.getUserId()));
                CommonInfo mchAppId = commonRepository.findOne(45);
                wxPay.setMch_appid(mchAppId.getValue());
                wxPay.setOpenid(userById.getMpId());
                //商户号id
                wxPay.setMchid(mchId.getValue());
                //随机字符
                wxPay.setNonce_str(WxPayUtils.generateNonceStr());
                //商户订单号  需保持唯一
                wxPay.setPartner_trade_no(one.getOrderNumber());
                //用户openId

                //NO_CHECK：不校验真实姓名
                //FORCE_CHECK：强校验真实姓名
                wxPay.setCheck_name("NO_CHECK");
                //转账金额 微信为分
                double v = Double.parseDouble(one.getMoney());
                Double mul = AmountCalUtils.mul(v, 100);
                Integer amount = mul.intValue();
                wxPay.setAmount(amount);
                //备注
                CommonInfo one2 = commonRepository.findOne(12);
                wxPay.setDesc(one2.getValue() + "提现金额到账");
                wxPay.setSign(WxPayUtils.createSign(BeanUtil.beanToMap(wxPay), key.getValue()));


                String xmlParam = XmlUtil.beanToXml(wxPay, WxPay.class);
                WeChatPayRequest weChatPayRequest = new WeChatPayRequest();

                String returnXml = null;
                try {
                    CommonInfo zsUlr = commonRepository.findOne(201);
                    returnXml = weChatPayRequest.request(zsUlr.getValue(), WxPayUtils.WX_COM_DO_TRANS_URL, xmlParam, true, mchId.getValue());
                    WxResult wxResult = XmlUtil.xmlToBean(returnXml, WxResult.class);
                    if (wxResult.getReturn_code().equals("SUCCESS")) {
                        if (one.getOrderNumber().equals(wxResult.getPartner_trade_no())) {
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            one.setState(1);
                            one.setOutAt(sdf.format(new Date()));
                            CashOut save = cashJpaRepository.save(one);
                            if (StringUtils.isNotEmpty(save.getUserId()) && save.getMerchantId() == null) {
                                UserInfo userInfo = userJpaRepository.getOne(Long.valueOf(save.getUserId()));
                                if (userInfo != null && userInfo.getOpenId() != null) {
                                    //提现通知消息
                                    cashOutSuccess(userInfo.getOpenId(), save.getOutAt(), save.getMoney(), "微信", commonRepository.findOne(19).getValue());
                                }
                                if (StringUtils.isNotEmpty(userInfo.getMpId())) {
                                    CommonInfo msgs2 = commonRepository.findOne(295);
                                    List<String> msgLists2 = new ArrayList<>();
                                    msgLists2.add(save.getMoney());
                                    msgLists2.add(save.getOutAt());
                                    msgLists2.add("具体到账时间请已微信为主，注意查收");
                                    AccountTokenServiceImpl.sendMsg(userInfo.getMpId(), msgs2.getValue(), msgLists2, 3);
                                }
                            }
                            return ResultUtil.success(one1.getZhifubaoName() + "转账成功");
                        } else {
                            return ResultUtil.error(-200, "转账失败！原因：" + wxResult.getErr_code_des());
                        }
                    } else {
                        return ResultUtil.error(-200, "转账失败！状态码：" + wxResult.getErr_code_des());
                    }
                } catch (Exception e) {
                    log.error("转账异常：" + e.getMessage(), e);
                    log.error("postWxTransfers 微信处理异常 ==>{}", ExceptionUtils.getStackTrace(e));
                }

            } else {
                //人工转账后改变状态的
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date now = new Date();
                one.setState(1);
                one.setOutAt(sdf.format(now));
                CashOut save = cashJpaRepository.save(one);
                if (save.getMerchantId() != null) {
                    return ResultUtil.success(one1.getZhifubaoName() + "转账成功");
                }
                String userId = save.getUserId();
                UserInfo userInfo = userJpaRepository.getOne(Long.valueOf(userId));
                if (userInfo != null && userInfo.getOpenId() != null) {
                    //推送提现通知消息
                    cashOutSuccess(userInfo.getOpenId(), save.getOutAt(), save.getMoney(), save.getZhifubao(), commonRepository.findOne(19).getValue());
                }
                if (StringUtils.isNotEmpty(userInfo.getMpId())) {
                    CommonInfo msgs2 = commonRepository.findOne(295);
                    List<String> msgLists2 = new ArrayList<>();
                    msgLists2.add(save.getMoney());
                    msgLists2.add(save.getOutAt());
                    msgLists2.add("具体到账时间请已支付宝为主，注意查收");
                    AccountTokenServiceImpl.sendMsg(userInfo.getMpId(), msgs2.getValue(), msgLists2, 3);
                }
                return ResultUtil.success(one1.getZhifubaoName() + "转账成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("转账出错了" + e.getMessage(), e);
        } finally {
            reentrantReadWriteLock.writeLock().unlock();
        }
        return ResultUtil.error(-200, "系统繁忙，请稍后再试！");
    }

    @RequestMapping(value = "/v1/refund/{cashId}/{content}", method = RequestMethod.POST)
    @ApiOperation("管理平台退款")
    @ResponseBody
    public Result refund(@PathVariable("cashId") Long cashId, @PathVariable("content") String content) {
        CashOut one = cashJpaRepository.findById(cashId).orElse(null);
        if (one == null) {
            return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
        }
        if (one.getState() != 0) {
            return ResultUtil.error(-100, "状态错误，已经转账或退款!");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        one.setState(-1);
        one.setRefund(content);
        one.setOutAt(sdf.format(new Date()));
        CashOut save = cashJpaRepository.save(one);
        //商户退款
        Long merchantId = save.getMerchantId();
        if (merchantId != null) {
            SelfMerchantApply m = selfMerchantApplyJpaRepository.findById(merchantId).orElse(null);
            //将金额退还
            selfMerchantApplyJpaRepository.updateMoneyAdd(m.getMoney().add(new BigDecimal(save.getMoney())), m.getId());
            iMoneyDetailsService.saveMerchant(m.getId(), 1, 4, sdf.format(new Date()) + "退款提醒", content, Double.parseDouble(save.getMoney()));
        } else { //用户退款
            String userId = save.getUserId();
            UserInfo userInfo = userJpaRepository.getOne(Long.valueOf(userId));
            if (userInfo != null) {
                //将金额退还
                userRepository.updateJiFenAdd(save.getMoney(), Long.parseLong(save.getUserId()));
                iMoneyDetailsService.saveBody(userInfo.getId(), 1, 4, sdf.format(new Date()) + "退款提醒", content, Double.parseDouble(save.getMoney()));
                if (userInfo.getOpenId() != null) {
                    //推送提现通知消息
                    refundSuccess(userInfo.getOpenId(), save.getOutAt(), save.getMoney(), commonRepository.findOne(19).getValue(), content);
                }
                if (StringUtils.isNotEmpty(userInfo.getMpId())) {
                    CommonInfo msgs2 = commonRepository.findOne(296);
                    List<String> msgLists2 = new ArrayList<>();
                    msgLists2.add(save.getMoney());
                    msgLists2.add(save.getCreateAt());
                    if (content.length() > 15) {
                        content = content.substring(0, 15) + "...";
                    }
                    msgLists2.add(content);
                    AccountTokenServiceImpl.sendMsg(userInfo.getMpId(), msgs2.getValue(), msgLists2, 4);
                }
            }
        }

        return ResultUtil.success();
    }


    /**
     * 瞄有券第三方转账
     *
     * @param alipay   支付宝账号
     * @param realname 真实姓名
     * @param money    支付金额
     * @param beizhu   备注
     */
    private void sendMoney(String alipay, String realname, String money, String beizhu) {
        CommonInfo three = commonRepository.findOne(30);
        String apkey = Config.MIAOYOUQUN_Key;
        if (three != null) {
            apkey = three.getValue();
        }
        long l = System.currentTimeMillis();
        String url = Config.MIAOYOUQUN_URL + "/platform/paymentToAlipay?apkey=" + apkey + "&thirdorder=" + l + "&beizhu=" + beizhu + "&realname=" + realname + "&money=" + money + "&alipay=" + alipay;
        String s = HttpClient.doGet(url);
    }

    /**
     * 查询某个用户的提现记录
     *
     * @param relationId
     * @return
     */
    @RequestMapping(value = "/list/{relationId}", method = RequestMethod.GET)
    @ApiOperation("用户端查询某个用户的提现记录")
    @ResponseBody
    public Result findOne(@PathVariable String relationId) {
        return iCashService.findOne(relationId);
    }

    /**
     * 前端获取已经提现了多少钱
     *
     * @param relationId
     * @return
     */
    @RequestMapping(value = "/countByRelationId/{relationId}", method = RequestMethod.GET)
    @ApiOperation("用户端获取已经提现了多少钱")
    @ResponseBody
    public Result countByRelationId(@PathVariable String relationId) {
        return ResultUtil.success(cashRepository.countByRelationId(relationId));
    }

    /**
     * 前端获取用户可以提现的金额
     *
     * @param userId
     * @return
     */
    @RequestMapping(value = "/money/{userId}", method = RequestMethod.GET)
    @ApiOperation("用户端获取用户可以提现的金额")
    @ResponseBody
    public Result cashOutMoney(@PathVariable Long userId) {
        UserInfo one = userJpaRepository.findById(userId).orElse(null);
        if (one != null) {
            return ResultUtil.success(one.getJifen());
        }
        return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
    }

    /**
     * 用户的信息查询
     *
     * @param userId
     * @return
     */
    @RequestMapping(value = "/userinfo/{userId}", method = RequestMethod.GET)
    @ApiOperation("用户端用户的信息查询")
    @ResponseBody
    public Result cashUserInfo(@PathVariable Long userId) {
        UserInfo one = userJpaRepository.findById(userId).orElse(null);
        if (one != null) {
            return ResultUtil.success(one);
        }
        return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
    }

    /**
     * 前端修改支付宝账号
     *
     * @param userId
     * @param zhifubao
     * @param zhifubaoName
     * @return
     */
    @RequestMapping(value = "/userinfo", method = RequestMethod.POST)
    @ApiOperation("用户端修改支付宝账号")
    @ResponseBody
    public Result updateZhiFuBao(@RequestParam Long userId, @RequestParam String zhifubao, @RequestParam String zhifubaoName) {
        UserInfo one = userJpaRepository.findById(userId).orElse(null);
        if (one != null) {
            one.setZhifubao(zhifubao);
            one.setZhifubaoName(zhifubaoName);
            UserInfo save = userJpaRepository.save(one);
            return ResultUtil.success(save);
        }
        return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
    }

    /**
     * 用户发起提现
     *
     * @param userId
     * @return
     */
    @IgnoreSecurity
    @RequestMapping(value = "/out/{userId}/{money}", method = RequestMethod.GET)
    @ApiOperation("用户端用户发起提现")
    @ResponseBody
    public Result cashOut(@PathVariable Long userId, @PathVariable BigDecimal money, Integer type) {
        if (money.compareTo(new BigDecimal("0.00")) <= 0) {
            return ResultUtil.error(-200, "提现金额有误，请刷新后重试！");
        }
        reentrantReadWriteLock.writeLock().lock();
        try {
            UserInfo one = userJpaRepository.findById(userId).orElse(null);
            CommonInfo url = commonRepository.findOne(19);
            if (one != null) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date now = new Date();
                if (one.getJifen() != null) {
                    //计算零钱
                    BigDecimal userMoney = new BigDecimal(one.getJifen()); //用户零钱
                    BigDecimal userJiFen = userMoney.subtract(money); //用户剩余零钱
                    if (userJiFen.doubleValue() < 0) {
                        return ResultUtil.error(-1, "零钱不足");
                    }
                    CashOut cashOut = new CashOut();
                    if (type == null || type == 1) {
                        cashOut.setType(1);
                    } else if (type == 2) {
                        cashOut.setType(2);
                        cashOut.setWxImg(one.getWxImg());
                    } else {
                        if (StringUtils.isEmpty(one.getBankCard()) || StringUtils.isEmpty(one.getBankCardName())) {
                            return ResultUtil.error(-200, "请先绑定银行卡信息！");
                        }
                        cashOut.setType(type);
                        cashOut.setBankCard(one.getBankCard());
                        cashOut.setBankCardName(one.getBankCardName());
                        cashOut.setBankCarUserName(one.getBankCarUserName());
                    }
                    cashOut.setOut(false);
                    cashOut.setType(type);
                    cashOut.setZhifubao(one.getZhifubao());
                    cashOut.setZhifubaoName(one.getZhifubaoName());
                    cashOut.setRelationId(one.getRelationId());
                    cashOut.setMoney(money.toString());
                    cashOut.setCreateAt(sdf.format(now));
                    cashOut.setUserId(String.valueOf(one.getId()));
                    cashOut.setState(0);
                    cashOut.setOrderNumber(String.valueOf(System.currentTimeMillis()));
                    CashOut save = cashJpaRepository.save(cashOut);
                    one.setJifen(userJiFen.toString());
                    //推送提现发起消息
                    if (StringUtils.isNotEmpty(one.getOpenId())) {
                        cashOut(one.getOpenId(), one.getNickName(), save.getCreateAt(), save.getMoney(), save.getZhifubao(), url.getValue());
                    }
                    userJpaRepository.save(one);
                    iMoneyDetailsService.saveBody(one.getId(), 2, 4, "用户提现", "发起提现，提现金额：-" + save.getMoney(), Double.parseDouble(save.getMoney()));
                    return ResultUtil.success(save);
                }
            }
            return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("用户提现异常" + e.getMessage(), e);
        } finally {
            reentrantReadWriteLock.writeLock().unlock();
        }
        return ResultUtil.error(-200, "系统繁忙，请稍后再试！");
    }

    @RequestMapping(value = "/out/merchantId", method = RequestMethod.GET)
    @ApiOperation("商户端商户发起提现")
    @ResponseBody
    public Result cashOutMerchantId(@RequestParam Long merchantId, @RequestParam String outMoney, Integer type) {
        if (Double.parseDouble(outMoney) <= 0) {
            return ResultUtil.error(-200, "提现金额有误，请刷新后重试！");
        }
        reentrantReadWriteLock.writeLock().lock();
        try {
            SelfMerchantApply one = selfMerchantApplyJpaRepository.findById(merchantId).orElse(null);
            if (one != null) {
                if (one.getMoney() != null) {
                    if (one.getMoney().doubleValue() < new BigDecimal(outMoney).doubleValue()) {
                        return ResultUtil.error(-1, "提现金额不足");
                    }
                    SelfStore selfStore = selfStoreJpaRepository.findByMerchantId(one.getId());
                    //提现申请
                    CashOut cashOut = new CashOut();
                    cashOut.setStoreId(selfStore.getStoreId());
                    cashOut.setOut(false);
                    cashOut.setZhifubao(one.getZhiFuBaoAccount());
                    cashOut.setZhifubaoName(one.getZhiFuBaoName());
                    cashOut.setMoney(outMoney);
                    cashOut.setCreateAt(DateUtil.createTime());
                    cashOut.setUserId(String.valueOf(one.getId()));
                    cashOut.setState(0);
                    cashOut.setOrderNumber(String.valueOf(System.currentTimeMillis()));
                    cashOut.setMerchantId(merchantId); //商户id
                    if (type == null || type == 1) {
                        cashOut.setType(1);
                    } else if (type == 2) {
                        cashOut.setType(2);
                        cashOut.setWxImg(one.getWxImg());
                    } else {
                        if (StringUtils.isEmpty(selfStore.getBankCard()) || StringUtils.isEmpty(selfStore.getBankCardName())) {
                            return ResultUtil.error(-200, "请先绑定银行卡信息！");
                        }
                        cashOut.setType(type);
                        cashOut.setBankCard(selfStore.getBankCard());
                        cashOut.setBankCardName(selfStore.getBankCardName());
                        cashOut.setBankCarUserName(selfStore.getBankCarUserName());
                    }
                    CashOut save = cashJpaRepository.save(cashOut);
                    //保存商户金额
                    selfMerchantApplyJpaRepository.updateMoneyLess(one.getMoney().subtract(new BigDecimal(outMoney)), merchantId);
                    //记录
                    iMoneyDetailsService.saveMerchant(one.getId(), 2, 4, "商户提现", "发起提现，提现金额：-" + save.getMoney(), Double.parseDouble(save.getMoney()));
                    return ResultUtil.success(save);
                }
            }
            return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("商户端提现异常：" + e.getMessage(), e);
        } finally {
            reentrantReadWriteLock.writeLock().unlock();
        }
        return ResultUtil.error(-200, "系统繁忙，请稍后再试！");
    }


    /**
     * 商户的提现记录
     *
     * @return
     */
    @RequestMapping(value = "/listByMerchantId", method = RequestMethod.GET)
    @ApiOperation("商户的提现记录")
    @ResponseBody
    public Result findOne(int page, int size, Long merchantId) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(new Sort.Order(Sort.Direction.DESC, "createAt")));
        return ResultUtil.success(cashJpaRepository.findByMerchantId(pageable, merchantId));
    }

    /**
     * 申请提现成功通知
     *
     * @param openId
     * @param name
     * @param date
     * @param money
     * @param payWay
     * @param url
     */
    private void cashOut(String openId, String name, String date, String money, String payWay, String url) {
        try {
            UserInfo userByWxId = userRepository.getUserByWxId(openId);
            MessageInfo messageInfo = new MessageInfo();
            messageInfo.setState(String.valueOf(5));
            messageInfo.setContent("您好，您的提现申请成功，预计三个工作日到账！提现金额" + money + " 元！支付宝收款账号 " + payWay);
            messageInfo.setTitle("提现通知");
            messageInfo.setUserName(userByWxId.getNickName());
            messageInfo.setUserId(String.valueOf(userByWxId.getId()));
            iMessageService.saveBody(messageInfo);

            //提现通知管理员openid
            CommonInfo one = commonRepository.findOne(18);
            //后台管理平台域名配置
            CommonInfo two = commonRepository.findOne(20);

            CommonInfo three = commonRepository.findOne(38);
            String apkey = Config.CashNotification;
            if (three != null) {
                apkey = three.getValue();
            }
            if (userByWxId.getClientid() != null) {
                userService.pushToSingle("提现通知", "您好，您的提现申请成功，预计三个工作日到账！提现金额" + money + " 元！支付宝收款账号 " + payWay, userByWxId.getClientid());
            }
            LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
            data.put("first", new TemplateMessageItem("您好，您的提现申请成功，预计三个工作日到账", "#d71345"));
            data.put("keyword1", new TemplateMessageItem(name, "#d71345"));
            data.put("keyword2", new TemplateMessageItem(date, "#d71345"));
            data.put("keyword3", new TemplateMessageItem(money + " 元", "#d71345"));
            data.put("keyword4", new TemplateMessageItem("支付宝收款账号 " + payWay, "#d71345"));
            data.put("remark", new TemplateMessageItem("感谢您的使用！如有疑问请在公众号中发送您的问题联系客服", null));
            accountService.sendWxMessage(apkey, data, openId, url);

            LinkedHashMap<String, TemplateMessageItem> data1 = new LinkedHashMap<>();
            data1.put("first", new TemplateMessageItem("收到一个提现申请！ 请尽快处理！", "#d71345"));
            data1.put("keyword1", new TemplateMessageItem(name, "#d71345"));
            data1.put("keyword2", new TemplateMessageItem(date, "#d71345"));
            data1.put("keyword3", new TemplateMessageItem(money + " 元", "#d71345"));
            data1.put("keyword4", new TemplateMessageItem("支付宝收款账号 " + payWay, "#d71345"));
            data1.put("remark", new TemplateMessageItem("感谢您的使用！如有疑问请在公众号中发送您的问题联系客服", null));
            accountService.sendWxMessage(apkey, data1, one.getValue() != null ? one.getValue() : Config.CashOpenId, two.getValue() != null ? two.getValue() : Config.CashAdmin);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 退款成功通知
     *
     * @param openId
     * @param date
     * @param money
     * @param url
     */
    private void refundSuccess(String openId, String date, String money, String url, String content) {
        try {
            UserInfo userByWxId = userRepository.getUserByWxId(openId);
            MessageInfo messageInfo = new MessageInfo();
            messageInfo.setState(String.valueOf(5));
            messageInfo.setContent(content);
            messageInfo.setTitle("提现失败提醒");
            messageInfo.setUserName(userByWxId.getNickName());
            messageInfo.setUserId(String.valueOf(userByWxId.getId()));
            iMessageService.saveBody(messageInfo);
            if (userByWxId.getClientid() != null) {
                userService.pushToSingle("提现失败提醒", content, userByWxId.getClientid());
            }
            CommonInfo three = commonRepository.findOne(77);
            String apkey = Config.TiXianSuccessNotification;
            if (three != null) {
                apkey = three.getValue();
            }
            LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
            data.put("first", new TemplateMessageItem("您好，您发起的提现失败了,原因："+content, "#d71345"));
            data.put("keyword1", new TemplateMessageItem(money + " 元", "#d71345"));
            data.put("keyword2", new TemplateMessageItem(date, "#d71345"));
            data.put("remark", new TemplateMessageItem("请您按照失败原因修改相关信息后，重新提现！", null));
            accountService.sendWxMessage(apkey, data, openId, url);

        } catch (Exception e) {

        }
    }


    /**
     * 提现成功通知
     *
     * @param openId
     * @param date
     * @param money
     * @param payWay
     * @param url
     */
    private void cashOutSuccess(String openId, String date, String money, String payWay, String url) {
        try {
            UserInfo userByWxId = userRepository.getUserByWxId(openId);
            MessageInfo messageInfo = new MessageInfo();
            messageInfo.setState(String.valueOf(5));
            messageInfo.setContent("您好，您的提现转账成功，请注意查收！提现金额【" + money + "元】！支付宝收款账号 " + payWay + "感谢您的使用！如有疑问请在公众号中发送您的问题联系客服");
            messageInfo.setTitle("提现成功通知");
            messageInfo.setUserName(userByWxId.getNickName());
            messageInfo.setUserId(String.valueOf(userByWxId.getId()));
            iMessageService.saveBody(messageInfo);
            if (userByWxId.getClientid() != null) {
                userService.pushToSingle("提现成功通知", "您好，您的提现转账成功，请注意查收！提现金额【" + money + "元】！支付宝收款账号 " + payWay + "感谢您的使用！如有疑问请在公众号中发送您的问题联系客服", userByWxId.getClientid());
            }
            CommonInfo three = commonRepository.findOne(39);
            String apkey = Config.TiXianSuccessNotification;
            if (three != null) {
                apkey = three.getValue();
            }
            LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
            data.put("first", new TemplateMessageItem("您好，您的提现转账成功，请注意查收", "#d71345"));
            data.put("keyword1", new TemplateMessageItem(money + " 元", "#d71345"));
            data.put("keyword2", new TemplateMessageItem(date, "#d71345"));
            data.put("remark", new TemplateMessageItem("支付宝收款账号 " + payWay + "感谢您的使用！如有疑问请在公众号中发送您的问题联系客服", null));
            accountService.sendWxMessage(apkey, data, openId, url);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/selectCarStatus")
    @ApiOperation("查询银行卡转账")
    public Result selectCarStatus(String orderNumber){
        String nonceStr = WXPayUtil.generateNonceStr();
        SortedMap<String, String> parameters = new TreeMap<String, String>();
        parameters.put("partner_trade_no", orderNumber);
        parameters.put("mch_id", commonRepository.findOne(76).getValue());
        parameters.put("nonce_str", nonceStr);
        String key = commonRepository.findOne(75).getValue();

        try {
            parameters.put("sign", WXPayUtil.generateSignature(parameters, key,
                    WXPayConstants.SignType.MD5));
        } catch (Exception e) {
            e.printStackTrace();
        }
        String data = RSAUtils.SortedMaptoXml(parameters);
        try {
            String result = RSAUtils.selectChatWithdrawal(data);

            WxCardResult wxResult = XmlUtil.xmlToBean(result, WxCardResult.class);
            return ResultUtil.success(wxResult);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("银行卡查询异常："+e.getMessage(),e);
        }
        return ResultUtil.error(-200,"查询失败！");
    }

    @PostMapping("/updateCardStatus")
    @ApiOperation("修改银行卡状态")
    public Result updateCardStatus(Long id,Integer status){
        CashOut cashOut = cashJpaRepository.findById(id).orElse(null);
        cashOut.setCardStatus(status);
        cashJpaRepository.save(cashOut);
        return ResultUtil.success();
    }


}
